package org.ee.core.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.ee.core.util.serialize.JsonUtil;
import org.springframework.web.filter.CommonsRequestLoggingFilter;

import java.util.Collections;

/**
 * 美化请求日志
 * @Author jokr
 * @Date 2025/8/29 10:37
 */
public class PrettyRequestLoggingFilter extends CommonsRequestLoggingFilter {
    private final ObjectMapper objectMapper= JsonUtil.getJsonMapper();

    public PrettyRequestLoggingFilter() {
        this.setIncludeQueryString(true);
        this.setIncludePayload(true);
        this.setIncludeHeaders(true);
        this.setIncludeClientInfo(true);
        this.setMaxPayloadLength(4096);
        this.setAfterMessagePrefix("REQUEST DATA-");
    }

    /**
     * 处理请求
     * @param request
     * @param message
     */
    @Override
    protected void afterRequest(HttpServletRequest request, String message) {
        StringBuilder sb = new StringBuilder();
        sb.append("\n==================== HTTP REQUEST BEGIN ===========================\n");
        sb.append("Method : ").append(request.getMethod()).append("\n");
        sb.append("URI    : ").append(request.getRequestURI()).append("\n");
        sb.append("Client : ").append(request.getRemoteAddr()).append("\n");
        sb.append("User   : ").append(request.getRemoteUser()).append("\n");

        //heards
        // Headers
        sb.append("Headers:\n");
        Collections.list(request.getHeaderNames()).forEach(name -> {
            sb.append("  ").append(name).append(": ").append(request.getHeader(name)).append("\n");
        });

        // GET 请求，记录 query params
        if ("GET".equalsIgnoreCase(request.getMethod()) && request.getQueryString() != null) {
            sb.append("Query Params:\n  ").append(request.getQueryString()).append("\n");
        }

        // POST 请求，记录 payload
        if ("POST".equalsIgnoreCase(request.getMethod()) && message.contains("payload=")) {
            String payload = message.substring(message.indexOf("payload=") + 8).trim();
            if (payload.endsWith("]")) payload = payload.substring(0, payload.length() - 1);

            if (!payload.isEmpty()) {
                sb.append("Payload:\n");

                String contentType = request.getContentType();
                if (contentType != null && contentType.contains("application/json")) {
                    // JSON 美化
                    try {
                        String pretty = objectMapper.writerWithDefaultPrettyPrinter()
                                .writeValueAsString(objectMapper.readTree(payload));
                        sb.append("Method [Request Body] \n");
                        sb.append(pretty).append("\n");
                    } catch (Exception e) {
                        sb.append(payload).append("\n");
                    }
                } else if (contentType != null && contentType.contains("application/x-www-form-urlencoded")) {
                    // form-data 美化
                    String[] pairs = payload.split("&");
                    sb.append("Method [Request POST]\n");
                    for (String pair : pairs) {
                        sb.append("  ").append(pair.replace("=", " : ")).append("\n");
                    }
                } else {
                    // 其他类型直接原样输出
                    sb.append(payload).append("\n");
                }
            }
        }

        sb.append("==================== HTTP REQUEST END ===========================");
        logger.info(sb.toString());
    }

    /**
     * 防止log4j日志输出两次
     * @param request
     * @param message
     */
    @Override
    protected void beforeRequest(HttpServletRequest request, String message) {
        // 不调用 super.beforeRequest()，避免输出默认日志
        // 如果需要，可以自己写一个美化版 before log
    }
}
